www.gusucode.com > VC++仿XP免费Prof UIS界面库-源码程序 > VC++仿XP免费Prof UIS界面库-源码程序/code/Src/ExtMouseCaptureSink.cpp
//Download by http://www.NewXing.com // This is part of the Professional User Interface Suite library. // Copyright (C) 2001-2004 FOSS Software, Inc. // All rights reserved. // // http://www.prof-uis.com // http://www.fossware.com // mailto:foss@fossware.com // // This source code can be used, modified and redistributed // under the terms of the license agreement that is included // in the Professional User Interface Suite package. // // Warranties and Disclaimers: // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND // INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. // IN NO EVENT WILL FOSS SOFTWARE INC. BE LIABLE FOR ANY DIRECT, // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES, // INCLUDING DAMAGES FOR LOSS OF PROFITS, LOSS OR INACCURACY OF DATA, // INCURRED BY ANY PERSON FROM SUCH PERSON'S USAGE OF THIS SOFTWARE // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. #include "stdafx.h" #if (!defined __EXT_MOUSECAPTURESINK_H) #include <../Src/ExtMouseCaptureSink.h> #endif #ifdef __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS #if (!defined __EXT_POPUP_MENU_WND_H) #include <ExtPopupMenuWnd.h> #endif #endif // __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CExtMouseCaptureSink #ifdef __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS volatile HHOOK CExtMouseCaptureSink::g_hMouseHook = NULL; volatile HWND CExtMouseCaptureSink::g_hWndCapture = NULL; CCriticalSection CExtMouseCaptureSink::g_cs; #endif // __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS CExtMouseCaptureSink::CExtMouseCaptureSink() { } CExtMouseCaptureSink::~CExtMouseCaptureSink() { } HWND CExtMouseCaptureSink::SetCapture( HWND hWnd ) { #ifdef __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS if( hWnd == NULL || ( ! ::IsWindow(hWnd) ) ) { ReleaseCapture(); return NULL; } HWND hWndOldCapture = NULL; CSingleLock _slo( &g_cs, TRUE ); if( g_hMouseHook == NULL ) { ASSERT( g_hWndCapture == NULL ); g_hMouseHook = ::SetWindowsHookEx( WH_MOUSE, _HookMouseProc, 0, ::GetCurrentThreadId() ); ASSERT( g_hMouseHook != NULL ); } else { ASSERT( g_hWndCapture != NULL ); hWndOldCapture = g_hWndCapture; } if( g_hMouseHook != NULL ) g_hWndCapture = hWnd; else { hWnd = g_hWndCapture = NULL; } _slo.Unlock(); if( hWndOldCapture != NULL && ::IsWindow( hWndOldCapture ) ) ::SendMessage( hWndOldCapture, WM_CAPTURECHANGED, 0L, LPARAM(hWnd) ); ///// (debug/preview) ::SendMessage( hWnd, WM_CAPTURECHANGED, 0L, LPARAM(hWnd) ); return hWnd; #else // __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS return ::SetCapture( hWnd ); #endif // else from __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS } HWND CExtMouseCaptureSink::GetCapture() { #ifdef __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS return g_hWndCapture; #else // __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS return ::GetCapture(); #endif // else from __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS } BOOL CExtMouseCaptureSink::ReleaseCapture() { #ifdef __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS if( g_hWndCapture == NULL ) return TRUE; HWND hWndOldCapture = NULL; CSingleLock _slo( &g_cs, TRUE ); if( g_hMouseHook != NULL ) { ASSERT( g_hWndCapture != NULL ); ::UnhookWindowsHookEx( g_hMouseHook ); g_hMouseHook = NULL; hWndOldCapture = g_hWndCapture; g_hWndCapture = NULL; } else { ASSERT( g_hWndCapture == NULL ); } _slo.Unlock(); if( hWndOldCapture != NULL && ::IsWindow( hWndOldCapture ) ) ::SendMessage( hWndOldCapture, WM_CAPTURECHANGED, 0L, 0L ); return TRUE; #else // __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS return ::ReleaseCapture(); #endif // else from __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS } #ifdef __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS LRESULT CALLBACK CExtMouseCaptureSink::_HookMouseProc( int nCode, // hook code WPARAM wParam, // message identifier LPARAM lParam // mouse coordinates ) { MOUSEHOOKSTRUCT * lpMS = (MOUSEHOOKSTRUCT*)lParam; ASSERT( lpMS != NULL ); HWND hWndHook = (HWND)g_hWndCapture; if( lpMS->hwnd != hWndHook && hWndHook != NULL && ::IsWindow(hWndHook) ) { UINT nMsgToSend = WM_NULL; switch( wParam ) { case WM_MOUSEMOVE: case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_LBUTTONDBLCLK: case WM_RBUTTONDOWN: case WM_RBUTTONUP: case WM_RBUTTONDBLCLK: case WM_MBUTTONDOWN: case WM_MBUTTONUP: case WM_MBUTTONDBLCLK: nMsgToSend = wParam; break; case WM_NCMOUSEMOVE: nMsgToSend = WM_MOUSEMOVE; break; case WM_NCLBUTTONDOWN: nMsgToSend = WM_LBUTTONDOWN; break; case WM_NCLBUTTONUP: nMsgToSend = WM_NCLBUTTONUP; break; case WM_NCLBUTTONDBLCLK: nMsgToSend = WM_LBUTTONDBLCLK; break; case WM_NCRBUTTONDOWN: nMsgToSend = WM_RBUTTONDOWN; break; case WM_NCRBUTTONUP: nMsgToSend = WM_RBUTTONUP; break; case WM_NCRBUTTONDBLCLK: nMsgToSend = WM_RBUTTONDBLCLK; break; case WM_NCMBUTTONDOWN: nMsgToSend = WM_MBUTTONDOWN; break; case WM_NCMBUTTONUP: nMsgToSend = WM_MBUTTONUP; break; case WM_NCMBUTTONDBLCLK: nMsgToSend = WM_MBUTTONDBLCLK; break; } // switch( wParam ) if( nMsgToSend != WM_NULL ) { WPARAM wParamMsg = 0L; if( CExtPopupMenuWnd::IsKeyPressed(VK_LBUTTON) ) wParamMsg |= MK_LBUTTON; if( CExtPopupMenuWnd::IsKeyPressed(VK_RBUTTON) ) wParamMsg |= MK_RBUTTON; if( CExtPopupMenuWnd::IsKeyPressed(VK_MBUTTON) ) wParamMsg |= MK_MBUTTON; if( CExtPopupMenuWnd::IsKeyPressed(VK_SHIFT) ) wParamMsg |= MK_SHIFT; if( CExtPopupMenuWnd::IsKeyPressed(VK_CONTROL) ) wParamMsg |= MK_CONTROL; CPoint pt( lpMS->pt ); VERIFY( ::ScreenToClient( hWndHook, &pt ) ); LPARAM lParamMsg = MAKELPARAM( pt.x, pt.y ); ::SendMessage( hWndHook, nMsgToSend, wParamMsg, lParamMsg ); return -1; // eat! } // if( nMsgToSend != WM_NULL ) } // if( hWndHook != NULL && ::IsWindow(hWndHook) ) return ::CallNextHookEx( g_hMouseHook, nCode, wParam, lParam ); } #endif // __EXT_MOUSECAPTURESINK_USES_WIN_HOOKS